package com.wanban.downloader.db

import android.util.Log
import androidx.lifecycle.ViewModel
import com.blankj.utilcode.util.SPUtils
import com.wanban.downloader.BuildConfig
import com.wanban.downloader.db.room.DownloadRoomUtils
import com.wanban.downloader.db.v3.DatabaseManager
import com.wanban.downloader.db.v3.DownloadSQLiteHelper
import com.wanban.downloader.model.DownloadParams
import com.wanban.downloader.model.Status
import com.wanban.downloader.utils.RxUtils
import java.lang.NullPointerException

object DatabaseUtils: ViewModel() {

    const val TAG = "NewDB"

    /**
     * 交换数据库，并返回未下载成功的数据
     */
    fun exchangeDatabase(complete: (tasks: ArrayList<DownloadEntity>) -> Unit){
        RxUtils.doObservable({
            val isExchangeDBV14 = SPUtils.getInstance().getBoolean("isExchangeDBV14", false)
            if (!isExchangeDBV14) {
                Log.d(TAG, "没有交换过数据表，准备进行数据交换...")
                SPUtils.getInstance().put("isExchangeDBV14", true)
                // 交换新旧表
                val roomDao = DownloadRoomUtils.getInstance().downloadDao()
                // 获取所有旧表
                val oldRoomTasks = roomDao.allTasks
                Log.d(TAG, "取出所有旧表的数据...")
                oldRoomTasks?.forEach { task ->
                    Log.d(TAG, "旧表 -> " + task.getFileName() +" -> 准备插入新表" )
                    DatabaseManager.getInstance()?.insert(task)
                }
                // 删除所有旧表数据
                Log.d(TAG, "数据交换完成，删除旧表..." )
                roomDao.deleteAll()
            }
            val currentTasks = DatabaseManager.getInstance()?.getAllTasksWithM3U8()
            if (currentTasks == null) {
                it.onError(NullPointerException())
                return@doObservable
            }
            if (BuildConfig.DEBUG) {
                Log.d(TAG, "新表当前数据量..." + (currentTasks.size))
            }
            var result = currentTasks.filter { it.state != Status.SUCCESS && it.state != Status.DELETE } as ArrayList
            result.forEach {
                if (canTaskRestart(it)) {
                    // 重置下载状态
                    it.state = Status.PENDING
                    it.retryTime = 0
                }
            }
            result = ArrayList(result.sortedBy { it.episode }.sortedBy { it.videoId })
            if (BuildConfig.DEBUG) {
                result.forEach {
                    Log.d(TAG, "未完成的数据..." + it.getFileName() +" -> " + it.state)
                }
            }
            it.onNext(result)
        },{ tasks ->
            if (tasks.isNullOrEmpty()) {
                complete(ArrayList())
            } else {
                complete(tasks)
            }
        },{
            complete(ArrayList())
        })
    }

    private fun canTaskRestart(task: DownloadEntity): Boolean {
        return task.state == Status.PREPARE || task.state == Status.START || task.state == Status.DOWNLOADING
                || (task.state == Status.ERROR && task.retryTime < DownloadParams.maxRetryTimes)
    }

    /**
     * 根据条件获取指定的任务
     */
    fun getTaskByUrl(videoUrl: String):DownloadEntity? {
        return DatabaseManager.getInstance()?.getTask(DownloadSQLiteHelper.Columns.URL +"=?", arrayOf(videoUrl))
    }

    fun getTask(selection: String, selectionArgs: Array<String>):DownloadEntity?{
        return DatabaseManager.getInstance()?.getTask(selection, selectionArgs)
    }

    fun getTasks(selection: String?, selectionArgs: Array<String>?): ArrayList<DownloadEntity>?{
        return DatabaseManager.getInstance()?.getTasks(selection, selectionArgs)
    }


    /**
     * 删除指定任务
     */
    fun deleteTask(url: String, complete: () -> Unit){
        RxUtils.doObservable({
            DatabaseManager.getInstance()?.delete(url)
            it.onNext(1)
        },{
            complete()
        },{
            complete()
        })
    }

    /**
     * 删除指定任务
     */
    fun deleteTaskSync(url: String){
        DatabaseManager.getInstance()?.delete(url)
    }

    /**
     * 插入或者更新下载任务
     */
    fun insertOrUpdateTask(entity: DownloadEntity, complete: () -> Unit) {
        RxUtils.doObservable({
            DatabaseManager.getInstance()?.insert(entity)
            it.onNext(1)
        }, {
            complete()
        }, {
            complete()
        })
    }

    fun insertOrUpdateTask(entity: DownloadEntity) {
        insertOrUpdateTask(entity){}
    }
}

